package cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

/** ABA的问题，展示
 * @author dengzhiyuan
 * @version 1.0
 * @time 2021/3/22 17:02
 */
public class CasABATestV2 {

    public static AtomicStampedReference<Integer> a = new AtomicStampedReference(new Integer(1),1);

    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("操作线程="+Thread.currentThread().getName()+",初始值="+a.getReference());
                try {
                    Integer expectNum = a.getReference();
                    Integer expectVersion = a.getStamp();
                    Integer newVersion = expectVersion+1;
                    Integer newNum = expectNum +1;
                    TimeUnit.SECONDS.sleep(1);
                    boolean b = a.compareAndSet(expectNum,newNum,expectVersion, newVersion);
                    System.out.println("操作线程="+Thread.currentThread().getName()+",CAS操作：="+b);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"主线程");
        thread.start();

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int expectNum = a.getReference();
                    int newNum = expectNum +1;
                    TimeUnit.MILLISECONDS.sleep(100);
                    a.compareAndSet(a.getReference(), a.getReference()+1, a.getStamp(), a.getStamp()+1);
                    System.out.println("操作线程="+Thread.currentThread().getName()+",[compareAndSet]="+a.getReference());
                    a.compareAndSet(a.getReference(), a.getReference()-1, a.getStamp(), a.getStamp()+1);
                    System.out.println("操作线程="+Thread.currentThread().getName()+",[compareAndSet]="+a.getReference());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"干扰线程");
        thread2.start();
    }


}
